﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using DataAssociations.ConnectionOptionPartials;
using DataAssociations.Repository;
using DataAssociations.Repository.Connection.RDBMSConnectionInterfaces;
using NUnit.Framework;

namespace DataAssociations.NUnitTests
{
    [TestFixture]
    public class NamingConventionFixture
    {
        [SetUp]
        public void Setup()
        {
            _models =
                Reflectioner.FindImplementationsOfType<IConnectionStringType>(
                    Assembly.Load("DataAssociations.Repository"));
            _guiClasses =
                Reflectioner.FindSubClasses<BaseUserControl>(Assembly.LoadFrom("DataAssociations.exe"));
        }

        private Type[] _models;
        private Type[] _guiClasses;

        [Test]
        public void EveryGuiControlHasAModel()
        {
            foreach (var guiClass in _guiClasses)
            {
                var modelName = BuildModelNameFromUIClass(guiClass);
                var model = _models.Where(x => x.Name == modelName).FirstOrDefault();
                Assert.IsNotNull(model);
            }
        }

        private static string BuildModelNameFromUIClass(Type guiClass)
        {
            return guiClass.Name.Substring(0,
                                           guiClass.Name.IndexOf("ConnectionForm")) + "ConnectionStringType";
        }

        private readonly Dictionary<Type, Func<string, string>> _interfaceMembersNamesConstructor
            = new Dictionary<Type, Func<string, string>>
                  {
                      {typeof (string), x => { return "textBox" + x; }},
                      {typeof (bool), x => { return "checkBox" + x; }},
                      {typeof (int?), x => { return "textBox" + x; }},
                  };

        [Test]
        public void EveryDisplayElementHasAModelProperty()
        {
            foreach (var guiClass in _guiClasses)
            {
                var modelName = BuildModelNameFromUIClass(guiClass);
                var model = _models.Where(x => x.Name == modelName).FirstOrDefault();
                foreach (var property in model.GetProperties().Where(x => x.GetSetMethod() != null))
                {
                    var interfaceObjectName = _interfaceMembersNamesConstructor[property.PropertyType](property.Name);
                    Assert.IsNotNull(
                        guiClass.GetField(interfaceObjectName, BindingFlags.NonPublic | BindingFlags.Instance),
                        string.Format("Not found {0} property for class {1}", interfaceObjectName, guiClass.Name));
                }
            }
        }
    }
}
